import { Message } from 'element-ui';
import { deepCopy } from '@u/common.js';

export default {
  install(Vue) {

    // v-input
    /* eslint-disable */
    function doInput(el, binding, node) {
    /* eslint-disable */
      const element = el.querySelector('input'),
        params = binding.value;
      if (params instanceof Object && params.reg && params.reg instanceof RegExp && params.belong && typeof params.belong == 'string') {
        document.addEventListener('compositionstart', function(e) { // 开始输入中文
          // console.log('start');
          if (element == e.target) {
            e.target.composing = true;
          }
        });
        document.addEventListener('compositionend', function(e) { // 结束输入中文
          // console.log('end');
          if (element == e.target) {
            e.target.composing = false;
            const str = 'node.context.' + params.belong,
              val = eval(str) ? eval(str).toString() : '',
              regArr = val.match(params.reg);
            if (val) {
              const result = regArr ? str + ' = ' + '"' + regArr[0] + '"' : str + ' = null';
              eval(result);
            }
          }
        });
        element.oninput = function(e) {
          const str = 'node.context.' + params.belong,
            val = eval(str) ? eval(str).toString() : '',
            regArr = val.match(params.reg);
          if (!e.target.composing) { // 不是输入中文时
            if (val) {
              const result = regArr ? str + ' = ' + '"' + regArr[0] + '"' : str + ' = null';
              eval(result);
            }
          }
        };
      }
    }
    Vue.directive('input', {
      bind(el, binding, node) {
        doInput(el, binding, node);
      },
      componentUpdated(el, binding, node) {
        doInput(el, binding, node);
      }
    });

    // v-blur
    /* eslint-disable */
    function doBlur(el, binding, node) {
    /* eslint-disable */
      const params = binding.value;
      if (params.removeBlur) {
        return;
      }
      if (params instanceof Object && params.reg && params.reg instanceof RegExp && params.belong && typeof params.belong == 'string') {
        // console.log(node.tag);
        el.querySelector('input').onblur = function() {
          const str = 'node.context.' + params.belong,
            val = eval(str) ? eval(str).toString() : eval(str) == 0 ? eval(str).toString() : '',
            isPass = params.reg.test(val);
          if (!isPass && val) {
            Message.error('输入不符合规范，请重新输入！');
            el.querySelector('input').focus();
            const result = str + ' = null';
            eval(result);
          }
        };
      }
    }
    Vue.directive('blur', {
      bind(el, binding, node) {
        doBlur(el, binding, node);
      },
      componentUpdated(el, binding, node) {
        if (binding.value.removeBlur != binding.oldValue.removeBlur) {
          doBlur(el, binding, node);
        }
      }
    });

    // v-tab
    function doTab(el, binding) {
      const params = deepCopy(binding.value);
      params.area = params.area ? params.area.toLowerCase() + '-tab' : 'tab';
      if (params.removeTab) { // 不需要 tab 切换
        el.removeAttribute(params.area);
        el.onkeydown = function(e) {
          if (e.keyCode == 9) {
            e.preventDefault();
            e.returnValue = false;
          }
        };
      } else { // 允许 tab 切换
        el.setAttribute(params.area, params.index);
        Vue.nextTick(() => {
          if (el.className.includes('el-date-editor') || el.querySelector('.el-date-editor')) { // 日期选择器、时间选择器禁用原生 tab
            el.querySelector('input').onkeydown = function(e) {
              if (e.keyCode == 9) {
                e.preventDefault();
                e.returnValue = false;
                const tag = findePrevOrNext(params.index, params.area, params.max, e.shiftKey);
                if (tag) {
                  tag.focus();
                  if (tag.getAttribute('type') != 'checkbox') { // 复选框、开关不点击
                    tag.click();
                  }
                } else {
                  Message.closeAll();
                  Message.warning(e.shiftKey ? '没有上一个了' : '没有下一个了');
                }
              }
            };
          } else {
            el.onkeydown = function(e) {
              if (e.keyCode == 9) {
                const tag = findePrevOrNext(params.index, params.area, params.max, e.shiftKey);
                if (tag) {
                  tag.focus();
                  if (tag.getAttribute('type') != 'checkbox') { // 复选框、开关不点击
                    tag.click();
                  }
                } else {
                  Message.closeAll();
                  Message.warning(e.shiftKey ? '没有上一个了' : '没有下一个了');
                }
              }
            };
          }
        });
      }
      function findePrevOrNext(index, area, max, type) { // 找到上一个或下一个输入项，type：false 为查找下一项，true 为查找上一项
        let prev = null, next = null, tag = null;
        if (type) { // 查找上一项
          for (let i = Number(index) - 1; i > 0; i--) {
            const p = document.querySelector(`[${ area }="${ i }"]`);
            if (p) {
              prev = p;
              break;
            }
          }
        } else {
          for (let i = Number(index) + 1; i <= max; i++) {
            const n = document.querySelector(`[${ area }="${ i }"]`);
            if (n) {
              next = n;
              break;
            }
          }
        }
        tag = type ? prev : next;
        if (tag) {
          if (tag.className.includes('el-radio-group') || tag.querySelector('.el-radio-group')) { // 按钮组
            tag = tag.querySelector('[tabindex="0"]') && tag.querySelector('[tabindex="0"]').querySelector('input')
            || tag.querySelector('[tabindex="-1"]');
          } else {
            tag = tag.querySelector('button') || tag.querySelector('input') || tag.querySelector('textarea');
          }
        }
        if (!tag && index > 0 && index <= max) {
          return findePrevOrNext(type ? index - 1 : index + 1, area, max, type)
        }
        return tag;
      }
    }
    Vue.directive('tab', {
      bind(el, binding) {
        doTab(el, binding);
      },
      componentUpdated(el, binding) {
        if (binding.value.removeTab != binding.oldValue.removeTab || binding.value.max != binding.oldValue.max) {
          doTab(el, binding);
        }
      }
    });
  }
};
